package com.idanchuang.component.mybatis.plus.plugins;

import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.SqlInfo;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
import com.idanchuang.component.core.helper.EnvContext;
import org.apache.ibatis.reflection.MetaObject;

import java.util.Collection;
import java.util.regex.Pattern;

/**
 * @author yjy
 * @date 2020/9/11 9:52
 **/
public class PressureTableNameParser implements AvailableSqlParser {

    private static ITableNameHandler tableNameHandler = new ITableNameHandler() {

        @Override
        public String process(MetaObject metaObject, String sql, String tableName) {
            String dynamicTableName = dynamicTableName(metaObject, sql, tableName);
            if (null != dynamicTableName && !dynamicTableName.equalsIgnoreCase(tableName)) {
                sql += " ";
                return sql.replaceAll("([\\s|,])" + tableName + "([,|\\s])", "$1"+dynamicTableName+"$2");
            }
            return sql;
        }

        @Override
        public String dynamicTableName(MetaObject metaObject, String sql, String tableName) {
            return tableName + "_pressure";
        }
    };

    @Override
    public SqlInfo parser(MetaObject metaObject, String sql) {
        if (allowProcess(metaObject) && EnvContext.isPressureForMysql()) {
            Collection<String> tables = new DcTableNameParser(sql).tables();
            if (CollectionUtils.isNotEmpty(tables)) {
                String parsedSql = sql;
                for (final String table : tables) {
                    if (EnvContext.isPressureForTable(table)) {
                        parsedSql = tableNameHandler.process(metaObject, parsedSql, table);
                    }
                }
                return SqlInfo.newInstance().setSql(parsedSql);
            }
        }
        return null;
    }


    /**
     * 判断是否允许执行
     * <p>例如：逻辑删除只解析 delete , update 操作</p>
     *
     * @param metaObject 元对象
     * @return true
     */
    public boolean allowProcess(MetaObject metaObject) {
        return true;
    }

}